/************************************************************************

								Heroes IV
					  Copyright 2001, The 3DO Company

	------------------------------------------------------------------
  						 abstract_combat_ai_spell_action.h

	$Header: $

	$NoKeywords: $

 ************************************************************************/

#if !defined( ABSTRACT_COMBAT_AI_SPELL_ACTION_H_INCLUDED )
#define ABSTRACT_COMBAT_AI_SPELL_ACTION_H_INCLUDED

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include "abstract_combat_ai_action.h"
#include "combat_creature_ptr.h"
#include "combat_spell_ptr.h"

class t_combat_ai;
enum  t_spell;
class t_spell_list;

class t_abstract_combat_ai_spell_action : public t_abstract_combat_ai_action
{
public:
	explicit t_abstract_combat_ai_spell_action( t_battlefield&		battlefield,
												t_combat_spell_ptr	spell,
											    bool				never_use = false,
											    double				weight = std::numeric_limits<double>::quiet_NaN(),
											    double				sp_adjusted_weight = std::numeric_limits<double>::quiet_NaN());

	void						calculate_sp_adjusted_weight(double best_non_spell_action_weight);
	double						get_sp_adjusted_weight(void) const;
	t_combat_spell_ptr const	get_spell(void) const;

protected:
	t_combat_spell_ptr	m_spell; // The spell to cast
	double				m_sp_adjusted_weight; // Weight after spell point adjustment
};

inline
t_abstract_combat_ai_spell_action::t_abstract_combat_ai_spell_action( t_battlefield& battlefield,
																	  t_combat_spell_ptr spell,
																	  bool never_use, 
																	  double weight, 
																	  double sp_adjusted_weight)
								 : t_abstract_combat_ai_action(battlefield, never_use, weight),
								   m_spell(spell), m_sp_adjusted_weight(sp_adjusted_weight)
{
}

inline
double t_abstract_combat_ai_spell_action::get_sp_adjusted_weight(void) const
{
	return m_sp_adjusted_weight;
}

inline
const t_combat_spell_ptr t_abstract_combat_ai_spell_action::get_spell(void) const
{
	return m_spell;
}


// ---------------------------------------------------------------
// generalized spell action
// ---------------------------------------------------------------
class t_combat_ai_spell_action : public t_abstract_combat_ai_spell_action
{
public:
	t_combat_ai_spell_action( t_battlefield& battlefield, t_combat_spell_ptr spell, double weight );

	// Do this action on the battlefield
	virtual void perform_action();
	virtual void weigh_action(t_combat_ai const& owner);
};

inline t_combat_ai_spell_action::t_combat_ai_spell_action( t_battlefield& battlefield,
														   t_combat_spell_ptr spell, double weight )
                               : t_abstract_combat_ai_spell_action( battlefield, spell, false, 
																	weight )
{
}

// get value of cancelling a list of spells
double	get_cancel_value( t_battlefield& battlefield, t_combat_creature const& target, 
						  t_spell_list const& spells );
double  get_damage_spell_weight( t_combat_creature const&	caster,
							     t_combat_creature const&	target,
								 t_spell					spell );
double  get_poison_value( t_combat_creature const& target, int power );
int		get_spell_cost_per_turn( t_combat_creature const& target );
double	get_spell_protection_value( t_combat_creature const&	caster,
								    t_combat_creature const&	target,
								    t_spell						spell,
								    double						target_value,
								    double						resistance_effect );

#endif // ABSTRACT_COMBAT_AI_SPELL_ACTION_H_INCLUDED
